package com.intelligentclass.controller;

import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.intelligentclass.constant.UserType;
import com.intelligentclass.entity.*;
import com.intelligentclass.exception.UserTypeException;
import com.intelligentclass.mydata.MyJson;
import com.intelligentclass.mydata.MyTreeNode;
import com.intelligentclass.services.*;
import com.intelligentclass.utils.JWTUtil;
import org.springframework.core.io.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;

@RestController
@CrossOrigin(origins="*")
public class TeachingController {

    private final TeacherService teacherService;
    private TeachingService teachingService;
    private CoursewareService coursewareService;
    private HistorypaperService historypaperService;
    private ExerciseService exerciseService;
    private SyllabusService syllabusService;

    private static final String COURSEWARE_PATH = "D:\\IntelligentClass\\Courseware\\";
    private static final String HISTORYPAPER_PATH = "D:\\IntelligentClass\\HistoryPaper\\";
    private static final String EXERCISE_PATH = "D:\\IntelligentClass\\Exercise\\";
    private static final String SYLLABUS_PATH = "D:\\IntelligentClass\\syllabus\\";

    @Autowired
    public TeachingController(TeachingService teachingService, CoursewareService coursewareService,
                              HistorypaperService historypaperService, ExerciseService exerciseService, TeacherService teacherService,
                              SyllabusService syllabusService) {
        this.teachingService = teachingService;
        this.coursewareService = coursewareService;
        this.historypaperService = historypaperService;
        this.exerciseService = exerciseService;
        this.teacherService = teacherService;
        this.syllabusService = syllabusService;
    }

    /**
     *
     * @param header
     *  must contain a valid token used to identify if the user is correct
     * @param cid
     * @return
     */
    @PostMapping("/api/teaching/getIntroduce")
    public ResponseEntity<?> getIntroduce(@RequestHeader Map<String, String> header, @RequestParam("cid") int cid) {

        MyJson json = new MyJson();

        String token = header.get("token");
        DecodedJWT jwt;
        try {
            jwt = JWTUtil.verifyToken(token);
        }
        catch (TokenExpiredException e) {
            json.setMessage("Token is expired");
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
        catch (Exception e) {
            System.exit(1);
            return null;
        }

        Teaching t = teachingService.searchTeaching(cid);
        if(t == null) {
            return ResponseEntity.badRequest().body("Error");
        }

        json.setStatus(200);
        json.setMessage("Success");
        String introduce = t.getIntroduce();
        if(introduce == null) {
            introduce = "该课程暂无简介";
        }
        json.addData("Introduce", introduce);
        return ResponseEntity.ok(json.toString());
    }

    @GetMapping("/api/teaching/getSyllabus")
    public ResponseEntity<?> getSyllabus(@RequestHeader Map<String, String> header, @RequestParam("cid") int cid) {
        MyJson json = new MyJson();
        String token = header.get("token");
        DecodedJWT jwt;
        boolean test = token == null;
        System.out.println(test);
        try {
            jwt = JWTUtil.verifyToken(token);
            int userType = jwt.getClaim("usertype").asInt();
//            int userType = UserType.STUDNET;
            if(userType != UserType.STUDENT && userType != UserType.TEACHER) {
                throw new UserTypeException();
            }
            else{
                try {
                    System.out.println(1);
                    String filePath = SYLLABUS_PATH + cid;
                    String name = syllabusService.getNameByCid(cid);
                    filePath += "\\" + name;

                    File file = new File(filePath);
                    System.out.println(file.getAbsolutePath());
                    if (file.exists() && file.isFile()) {
                        System.out.println(2);
                        Resource resource = new UrlResource(file.toURI());

                        System.out.println(3);
                        String contentType = Files.probeContentType(file.toPath());
                        if (contentType == null) {
                            contentType = "application/pdf;charset=UTF-8"; // 默认值
                        }
                        System.out.println(contentType);

                        System.out.println(4);
                        System.out.println(resource.getFilename());
                        String encodedFilename = URLEncoder.encode(resource.getFilename(), StandardCharsets.UTF_8);
                        return ResponseEntity.ok()
                                .contentType(MediaType.parseMediaType(contentType))
                                .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + encodedFilename + "\"")
                                .body(resource);

                    } else {
                        System.out.println(100);
                        return ResponseEntity.notFound().build();
                    }
                } catch (Exception e) {
                    System.out.println(200);
                    return ResponseEntity.internalServerError().build();
                }
            }
        }
        catch (TokenExpiredException e) {
            json.setMessage("Token is expired");
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
        catch(UserTypeException e){
            json.setMessage(e.getMessage());
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
        catch (Exception e) {
            System.out.println("Unexpected exception happened when try to get syllabus");
            System.exit(1);
            return null;
        }
    }

    @PostMapping("/api/teaching/uploadSyllabus")
    public ResponseEntity<?> uploadSyllabus(@RequestHeader Map<String, String> header,
                                            @RequestParam("cid") int cid,
                                            @RequestParam("file") MultipartFile file) {
        MyJson json = new MyJson();
        String token = header.get("token");
        DecodedJWT jwt;
        boolean test = token == null;
        try{
            jwt = JWTUtil.verifyToken(token);
            int userType = jwt.getClaim("usertype").asInt();
//            int userType = UserType.TEACHER;
            if(userType != UserType.TEACHER) {
                throw new UserTypeException("Insufficient permission");
            }
        }
        catch(UserTypeException e){
            json.setMessage(e.getMessage());
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
        catch(TokenExpiredException e) {
            json.setMessage("Token is expired");
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
        catch (Exception e) {
            json.setMessage("Unexpected exception happened when try to get syllabus");
            System.exit(1);
            return null;
        }

        String folderPath = SYLLABUS_PATH + cid;
        File folder = new File(folderPath);
        if(!folder.exists()) {
            folder.mkdirs();
        }

        String name = file.getOriginalFilename();

        Syllabus check = syllabusService.getByCid(cid);
        Syllabus syllabus;
        if(check == null){
            syllabus = new Syllabus();
            syllabus.setCid(cid);
            syllabus.setName(name);
            syllabusService.save(syllabus);
        }
        else {
            syllabus = check;
            syllabus.setName(name);
            syllabusService.save(syllabus);
            for(String s: folder.list()){
                String p = folderPath + File.separator + s;
                File f = new File(p);
                if(f.exists()){
                    f.delete();
                }
            }
        }

        Path path = Paths.get(folderPath, name);
        try {
            Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
            json.setMessage("Success");
            json.setStatus(200);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
        catch(IOException e) {
            json.setMessage("Unexpected error occurred when writing file to the directory");
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
    }

    /**
     *
     * @param header
     *      header must contain a valid token to identify the user
     * @param cid
     *      the id of this teaching
     * @return
     */
    @GetMapping("/api/teaching/resource/coursewareList")
    public ResponseEntity<?> getCoursewareList(@RequestHeader Map<String, String> header, @RequestParam("cid") int cid) {
        MyJson json = new MyJson();
        System.out.println("000");
        String token = header.get("token");
        System.out.println("111");
        DecodedJWT jwt;
        boolean test = token == null;
        try{
            System.out.println("222");
            jwt = JWTUtil.verifyToken(token);
            int userType = jwt.getClaim("usertype").asInt();
//            int username = jwt.getClaim("username").asInt();
//            int userType = UserType.STUDNET;
            if(userType != UserType.STUDENT && userType != UserType.TEACHER) {
                throw new UserTypeException("Insufficient permission");
            }
            else{
                System.out.println(333);
                List<Courseware> list = coursewareService.getAllCoursewaresByCid(cid);
                System.out.println(444);
                System.out.println(list);
                if(list == null || list.isEmpty()) {
                    json.setMessage("No courseware found");
                    json.setStatus(400);
                    json.addData("status", 0);
                    return ResponseEntity.ok().body(json);
                }

                //Create file tree
                Map<Integer, MyTreeNode> nodes = new HashMap<>();
                for(Courseware courseware : list) {
                    MyTreeNode node = new MyTreeNode();
                    node.setId(courseware.getCoursewareid());
                    node.setName(courseware.getName());
                    node.setIsLeaf(courseware.getIsLeaf());
                    nodes.put(courseware.getCoursewareid(), node);
                }

                List<MyTreeNode> roots = new ArrayList<>();
                for(Courseware courseware : list) {
                    MyTreeNode currentNode = nodes.get(courseware.getCoursewareid());
                    if(courseware.getParent() == 0) {
                        if(!courseware.getName().equals("root")) {
                            System.out.println("add");
                            roots.add(currentNode);
                        }
                    }
                    else{
                        MyTreeNode parent = nodes.get(courseware.getParent());
                        if(parent != null) {
                            parent.addChild(currentNode);
                        }
                    }
                }

                json.setMessage("Success");
                json.setStatus(200);
                json.addData("status", 0);
                json.addData("CoursewareList", roots);
                return  ResponseEntity.ok().body(json);
            }
        }
        catch(UserTypeException e){
            json.setMessage(e.getMessage());
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
    }

    /**
     * This function is for previewing or downloading courseware
     *
     * @param header
     * @param coursewareid
     * @return
     */
    @GetMapping("/api/teaching/resource/getCourseware")
    public ResponseEntity<?> getCourseware(@RequestHeader Map<String, String> header, @RequestParam("coursewareid") int coursewareid) {

        MyJson json = new MyJson();
        String token = header.get("token");
        DecodedJWT jwt;
        boolean test = token == null;
        try{
            jwt = JWTUtil.verifyToken(token);
            int userType = jwt.getClaim("usertype").asInt();
//            int username = jwt.getClaim("username").asInt();
//            int userType = UserType.STUDNET;
            if(userType != UserType.STUDENT && userType != UserType.TEACHER) {
                throw new UserTypeException("Insufficient permission");
            }

            Courseware courseware = coursewareService.getCoursewareById(coursewareid);
            if(courseware == null) {
                json.setMessage("Courseware not found");
                json.setStatus(400);
                json.addData("status", 0);
                return ResponseEntity.ok().body(json);
            }

            try {
//                String path = courseware.getParent();
                String path = COURSEWARE_PATH + courseware.getCid() + "\\" + courseware.getName();
                File file = new File(path);

                if(!file.exists()) {
                    json.setMessage("Courseware not found");
                    json.setStatus(400);
                    json.addData("status", 0);
                    return ResponseEntity.ok().body(json);
                }

                Resource resource = new UrlResource(file.toURI());
                String contentType = Files.probeContentType(file.toPath());
                if(contentType == null) {
                    contentType = "application/octet-stream";
                }
                System.out.println(contentType);

                String encodedFilename = URLEncoder.encode(resource.getFilename(), StandardCharsets.UTF_8);

                return ResponseEntity.ok()
                        .contentType(MediaType.parseMediaType(contentType))
                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encodedFilename + "\"")
                        .body(resource);

            }catch(Exception e){
                json.setMessage("Courseware not found");
                json.setStatus(400);
                json.addData("status", 0);
                return ResponseEntity.ok().body(json);
            }
        }
        catch(UserTypeException e){
            json.setMessage(e.getMessage());
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
    }

    @GetMapping("/api/teaching/resource/historypaperlist")
    public ResponseEntity<?> getHistoryPaperList(@RequestHeader Map<String, String> header, @RequestParam("cid") int cid){
        MyJson json = new MyJson();
        System.out.println("000");
        String token = header.get("token");
        System.out.println("111");
        DecodedJWT jwt;
        boolean test = token == null;
        try{
            System.out.println("222");
            jwt = JWTUtil.verifyToken(token);
            int userType = jwt.getClaim("usertype").asInt();
//            int username = jwt.getClaim("username").asInt();
//            int userType = UserType.STUDNET;
            if(userType != UserType.STUDENT && userType != UserType.TEACHER) {
                throw new UserTypeException("Insufficient permission");
            }
            else{
                System.out.println(333);
                List<Historypaper> list = historypaperService.getAllHistorypaperByCid(cid);
                System.out.println(444);
                System.out.println(list);
                if(list == null || list.isEmpty()) {
                    json.setMessage("No courseware found");
                    json.setStatus(400);
                    json.addData("status", 0);
                    return ResponseEntity.ok().body(json);
                }

                //Create file tree
                Map<Integer, MyTreeNode> nodes = new HashMap<>();
                for(Historypaper historypaper : list) {
                    MyTreeNode node = new MyTreeNode();
                    node.setId(historypaper.getPaperId());
                    node.setName(historypaper.getName());
                    node.setIsLeaf(historypaper.getIsLeaf());
                    nodes.put(historypaper.getPaperId(), node);
                }

                List<MyTreeNode> roots = new ArrayList<>();
                for(Historypaper historypaper : list) {
                    MyTreeNode currentNode = nodes.get(historypaper.getPaperId());
                    if(historypaper.getParent() == 0) {
                        if(!historypaper.getName().equals("root")) {
                            System.out.println("add");
                            roots.add(currentNode);
                        }
                    }
                    else{
                        MyTreeNode parent = nodes.get(historypaper.getParent());
                        if(parent != null) {
                            parent.addChild(currentNode);
                        }
                    }
                }

                json.setMessage("Success");
                json.setStatus(200);
                json.addData("status", 0);
                json.addData("CoursewareList", roots);
                return  ResponseEntity.ok().body(json);
            }
        }
        catch(UserTypeException e){
            json.setMessage(e.getMessage());
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
    }

    @GetMapping("/api/teaching/resource/getHistorypaper")
    public ResponseEntity<?> getHistoryPaper(@RequestHeader Map<String, String> header, @RequestParam("paperid") int paperid){


        MyJson json = new MyJson();
        String token = header.get("token");
        DecodedJWT jwt;
        boolean test = token == null;
        try{
            jwt = JWTUtil.verifyToken(token);
            int userType = jwt.getClaim("usertype").asInt();
//            int username = jwt.getClaim("username").asInt();
//            int userType = UserType.STUDNET;
            if(userType != UserType.STUDENT && userType != UserType.TEACHER) {
                throw new UserTypeException("Insufficient permission");
            }

            Historypaper historyPaper = historypaperService.getHistorypaperById(paperid);
            if(historyPaper == null) {
                json.setMessage("Courseware not found");
                json.setStatus(400);
                json.addData("status", 0);
                return ResponseEntity.ok().body(json);
            }

            try {
//                String path = courseware.getParent();
                String path = HISTORYPAPER_PATH + historyPaper.getCid() + "\\" + historyPaper.getName();
                File file = new File(path);

                if(!file.exists()) {
                    json.setMessage("Courseware not found");
                    json.setStatus(400);
                    json.addData("status", 0);
                    return ResponseEntity.ok().body(json);
                }

                Resource resource = new UrlResource(file.toURI());
                String contentType = Files.probeContentType(file.toPath());
                if(contentType == null) {
                    contentType = "application/octet-stream";
                }
                System.out.println(contentType);

                String encodedFilename = URLEncoder.encode(resource.getFilename(), StandardCharsets.UTF_8);

                return ResponseEntity.ok()
                        .contentType(MediaType.parseMediaType(contentType))
                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encodedFilename + "\"")
                        .body(resource);

            }catch(Exception e){
                json.setMessage("paper not found");
                json.setStatus(400);
                json.addData("status", 0);
                return ResponseEntity.ok().body(json);
            }
        }
        catch(UserTypeException e){
            json.setMessage(e.getMessage());
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
    }

    @GetMapping("/api/teaching/resource/exerciseList")
    public ResponseEntity<?> getExerciseList(@RequestHeader Map<String, String> header, @RequestParam("cid") int cid){
        MyJson json = new MyJson();
        System.out.println("000");
        String token = header.get("token");
        System.out.println("111");
        DecodedJWT jwt;
        boolean test = token == null;
        try{
            System.out.println("222");
            jwt = JWTUtil.verifyToken(token);
            int userType = jwt.getClaim("usertype").asInt();
//            int username = jwt.getClaim("username").asInt();
//            int userType = UserType.STUDNET;
            if(userType != UserType.STUDENT && userType != UserType.TEACHER) {
                throw new UserTypeException("Insufficient permission");
            }
            else{
                System.out.println(333);
                List<Exercise> list = exerciseService.getAllExercisesByCid(cid);
                System.out.println(444);
                System.out.println(list);
                if(list == null || list.isEmpty()) {
                    json.setMessage("No courseware found");
                    json.setStatus(400);
                    json.addData("status", 0);
                    return ResponseEntity.ok().body(json);
                }

                //Create file tree
                Map<Integer, MyTreeNode> nodes = new HashMap<>();
                for(Exercise exercise : list) {
                    MyTreeNode node = new MyTreeNode();
                    node.setId(exercise.getEid());
                    node.setName(exercise.getName());
                    node.setIsLeaf(exercise.getIsLeaf());
                    nodes.put(exercise.getEid(), node);
                }

                List<MyTreeNode> roots = new ArrayList<>();
                for(Exercise exercise : list) {
                    MyTreeNode currentNode = nodes.get(exercise.getEid());
                    if(exercise.getParent() == 0) {
                        if(!exercise.getName().equals("root")) {
                            System.out.println("add");
                            roots.add(currentNode);
                        }
                    }
                    else{
                        MyTreeNode parent = nodes.get(exercise.getParent());
                        if(parent != null) {
                            parent.addChild(currentNode);
                        }
                    }
                }

                json.setMessage("Success");
                json.setStatus(200);
                json.addData("status", 0);
                json.addData("CoursewareList", roots);
                return  ResponseEntity.ok().body(json);
            }
        }
        catch(UserTypeException e){
            json.setMessage(e.getMessage());
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
    }

    @GetMapping("/api/teaching/resource/getExercise")
    public ResponseEntity<?> getExercise(@RequestHeader Map<String, String> header, @RequestParam("eid") int eid){

        MyJson json = new MyJson();
        String token = header.get("token");
        DecodedJWT jwt;
        boolean test = token == null;
        try{
            jwt = JWTUtil.verifyToken(token);
            int userType = jwt.getClaim("usertype").asInt();
//            int username = jwt.getClaim("username").asInt();
//            int userType = UserType.STUDNET;
            if(userType != UserType.STUDENT && userType != UserType.TEACHER) {
                throw new UserTypeException("Insufficient permission");
            }

            Exercise exercise = exerciseService.getExerciseById(eid);
            if(exercise == null) {
                json.setMessage("Courseware not found");
                json.setStatus(400);
                json.addData("status", 0);
                return ResponseEntity.ok().body(json);
            }

            try {
//                String path = courseware.getParent();
                String path = EXERCISE_PATH + exercise.getCid() + "\\" + exercise.getName();
                File file = new File(path);

                if(!file.exists()) {
                    json.setMessage("Courseware not found");
                    json.setStatus(400);
                    json.addData("status", 0);
                    return ResponseEntity.ok().body(json);
                }

                Resource resource = new UrlResource(file.toURI());
                String contentType = Files.probeContentType(file.toPath());
                if(contentType == null) {
                    contentType = "application/octet-stream";
                }
                System.out.println(contentType);

                String encodedFilename = URLEncoder.encode(resource.getFilename(), StandardCharsets.UTF_8);

                return ResponseEntity.ok()
                        .contentType(MediaType.parseMediaType(contentType))
                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encodedFilename + "\"")
                        .body(resource);

            }catch(Exception e){
                json.setMessage("paper not found");
                json.setStatus(400);
                json.addData("status", 0);
                return ResponseEntity.ok().body(json);
            }
        }
        catch(UserTypeException e){
            json.setMessage(e.getMessage());
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
        catch(TokenExpiredException e){
            json.setMessage("This token is expired");
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
    }

    /**
     *
     * @param header must contain a valid token to identify the user
     * @param file a file stream to download file
     * @param cid the number of this class
     * @param parent the parent directory of this file
     * @return
     */
    @PostMapping("/api/teaching/resource/uploadCourseware")
    public ResponseEntity<?> uploadCourseware(
            @RequestHeader Map<String, String> header,
            @RequestParam("file") MultipartFile file,
            @RequestParam("cid") int cid,
            @RequestParam("parent") int parent
            ){


        MyJson json = new MyJson();
        String token = header.get("token");
        DecodedJWT jwt;
        boolean test = token == null;
        try{
            jwt = JWTUtil.verifyToken(token);
            int userType = jwt.getClaim("usertype").asInt();
//            int userType = UserType.TEACHER;
            if(userType != UserType.TEACHER){
                throw new UserTypeException("Insufficient permission");
            }

            String name = file.getOriginalFilename();

            Courseware check = coursewareService.getCourseware(cid, name, parent);

            Courseware courseware;
            if(check != null) {
                courseware = check;
                json.setMessage("Courseware has existed");
                json.setStatus(200);
                json.addData("status", 0);
                return ResponseEntity.ok().body(json);
            }
            else {
                courseware = new Courseware(name, cid, parent, 1);
                courseware = coursewareService.save(courseware);
                String folderPath = COURSEWARE_PATH + courseware.getCid();

                File folder = new File(folderPath);
                if (!folder.exists()) {
                    folder.mkdirs();
                }

                Path path = new File(folderPath, name).toPath();
                Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);

                json.setMessage("Success");
                json.setStatus(200);
                json.addData("status", 0);

                return ResponseEntity.ok().body(json);
            }

        }
        catch(TokenExpiredException e){
            json.setMessage("This token is expired");
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
        catch(UserTypeException e){
            json.setMessage("Insufficient permission");
            json.setStatus(400);
            json.addData("status", 400);
            return ResponseEntity.ok().body(json);
        }
        catch(Exception e){
            json.setMessage(e.getMessage());
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
    }

    @PostMapping("/api/teaching/resource/createCoursewareDir")
    public ResponseEntity<?> createCoursewareDir(@RequestHeader Map<String, String> header,
                                                 @RequestParam("cid") int cid,
                                                 @RequestParam("parent") int parent,
                                                 @RequestParam("name") String name){
        MyJson json = new MyJson();
        String token = header.get("token");
        DecodedJWT jwt;
        boolean test = token == null;

        try{
            jwt = JWTUtil.verifyToken(token);
            int userType = jwt.getClaim("usertype").asInt();
//            int userType = UserType.TEACHER;
            if(userType != UserType.TEACHER){
                throw new UserTypeException("Insufficient permission");
            }

            Courseware check = coursewareService.getCoursewareByCidAndName(cid, name);

            Courseware courseware;
            if(check == null) {
                courseware = new Courseware(name, cid, parent, 0);
                courseware = coursewareService.save(courseware);
            }
            else courseware = check;


            json.setMessage("Success");
            json.setStatus(200);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);

        }
        catch(UserTypeException e){
            json.setMessage("Insufficient permission");
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
        catch(TokenExpiredException e){
            json.setMessage("This token is expired");
            json.setStatus(400);
            json.addData("status", 400);
            return ResponseEntity.ok().body(json);
        }
        catch(Exception e){
            json.setMessage(e.getMessage());
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
    }

    @PostMapping("/api/teaching/resource/uploadHistoryPaper")
    public ResponseEntity<?> uploadHistoryPaper(@RequestHeader Map<String, String> header,
                                                @RequestParam("file") MultipartFile file,
                                                @RequestParam("cid") int cid,
                                                @RequestParam("parent") int parent){
        MyJson json = new MyJson();
        String token = header.get("token");
        DecodedJWT jwt;
        boolean test = token == null;
        try{
            jwt = JWTUtil.verifyToken(token);
            int userType = jwt.getClaim("usertype").asInt();
//            int userType = UserType.TEACHER;
            if(userType != UserType.TEACHER){
                throw new UserTypeException("Insufficient permission");
            }

            String name = file.getOriginalFilename();
            Historypaper check = historypaperService.getHistorypaper(cid, name, parent);

            Historypaper historypaper;
            if(check != null) {
                historypaper = check;
                json.setMessage("Courseware has existed");
                json.setStatus(200);
                json.addData("status", 0);
                return ResponseEntity.ok().body(json);
            }
            else {
                historypaper = new Historypaper(name, cid, parent, 1);
                historypaper = historypaperService.save(historypaper);
                String folderPath = HISTORYPAPER_PATH + historypaper.getCid();

                File folder = new File(folderPath);
                if (!folder.exists()) {
                    folder.mkdirs();
                }

                Path path = new File(folderPath, name).toPath();
                Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);

                json.setMessage("Success");
                json.setStatus(200);
                json.addData("status", 0);

                return ResponseEntity.ok().body(json);
            }

        }
        catch(TokenExpiredException e){
            json.setMessage("This token is expired");
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
        catch(UserTypeException e){
            json.setMessage("Insufficient permission");
            json.setStatus(400);
            json.addData("status", 400);
            return ResponseEntity.ok().body(json);
        }
        catch(Exception e){
            json.setMessage(e.getMessage());
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
    }

    @PostMapping("/api/teaching/resource/createHistoryPaperDir")
    public ResponseEntity<?> createHistoryPaperDir(@RequestHeader Map<String, String> header,
                                                   @RequestParam("cid") int cid,
                                                   @RequestParam("parent") int parent,
                                                   @RequestParam("name") String name){
        MyJson json = new MyJson();
        String token = header.get("token");
        DecodedJWT jwt;
        boolean test = token == null;

        try{
            jwt = JWTUtil.verifyToken(token);
            int userType = jwt.getClaim("usertype").asInt();
//            int userType = UserType.TEACHER;
            if(userType != UserType.TEACHER){
                throw new UserTypeException("Insufficient permission");
            }

            Historypaper check = historypaperService.getHistoryPaperByCidAndName(cid, name);
            Historypaper courseware;
            if(check == null) {
                courseware = new Historypaper(name, cid, parent, 0);
                courseware = historypaperService.save(courseware);
            }
            else courseware = check;

            json.setMessage("Success");
            json.setStatus(200);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);

        }
        catch(UserTypeException e){
            json.setMessage("Insufficient permission");
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
        catch(TokenExpiredException e){
            json.setMessage("This token is expired");
            json.setStatus(400);
            json.addData("status", 400);
            return ResponseEntity.ok().body(json);
        }
        catch(Exception e){
            json.setMessage(e.getMessage());
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
    }

    @PostMapping("/api/teaching/resource/uploadExercise")
    public ResponseEntity<?> uploadExercise(@RequestHeader Map<String, String> header,
                                            @RequestParam("file") MultipartFile file,
                                            @RequestParam("cid") int cid,
                                            @RequestParam("parent") int parent){
        MyJson json = new MyJson();
        String token = header.get("token");
        DecodedJWT jwt;
        boolean test = token == null;
        try{
            jwt = JWTUtil.verifyToken(token);
            int userType = jwt.getClaim("usertype").asInt();
//            int userType = UserType.TEACHER;
            if(userType != UserType.TEACHER){
                throw new UserTypeException("Insufficient permission");
            }

            String name = file.getOriginalFilename();

            Exercise check = exerciseService.getExercise(cid, name, parent);

            Exercise exercise;
            if(check != null) {
                exercise = check;
                json.setMessage("Courseware has existed");
                json.setStatus(200);
                json.addData("status", 0);
                return ResponseEntity.ok().body(json);
            }
            else {

                exercise = new Exercise(name, cid, parent, 1);
                String folderPath = EXERCISE_PATH + exercise.getCid();

                File folder = new File(folderPath);
                if (!folder.exists()) {
                    folder.mkdirs();
                }

                Path path = new File(folderPath, name).toPath();
                Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);

                json.setMessage("Success");
                json.setStatus(200);
                json.addData("status", 0);

                return ResponseEntity.ok().body(json);
            }

        }
        catch(TokenExpiredException e){
            json.setMessage("This token is expired");
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
        catch(UserTypeException e){
            json.setMessage("Insufficient permission");
            json.setStatus(400);
            json.addData("status", 400);
            return ResponseEntity.ok().body(json);
        }
        catch(Exception e){
            json.setMessage(e.getMessage());
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
    }

    @PostMapping("/api/teaching/resource/createExercisePaperDir")
    public ResponseEntity<?> createExercisePaperDir(@RequestHeader Map<String, String> header,
                                                    @RequestParam("cid") int cid,
                                                    @RequestParam("parent") int parent,
                                                    @RequestParam("name") String name){
        MyJson json = new MyJson();
        String token = header.get("token");
        DecodedJWT jwt;
        boolean test = token == null;

        try{
            jwt = JWTUtil.verifyToken(token);
            int userType = jwt.getClaim("usertype").asInt();
//            int userType = UserType.TEACHER;
            if(userType != UserType.TEACHER){
                throw new UserTypeException("Insufficient permission");
            }

            Exercise check = exerciseService.getExerciseeByCidAndName(cid, name);

            Exercise exercise;
            if(check == null) {
                exercise = new Exercise(name, cid, parent, 0);
                exercise = exerciseService.save(exercise);
            }
            else exercise = check;


            json.setMessage("Success");
            json.setStatus(200);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);

        }
        catch(UserTypeException e){
            json.setMessage("Insufficient permission");
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
        catch(TokenExpiredException e){
            json.setMessage("This token is expired");
            json.setStatus(400);
            json.addData("status", 400);
            return ResponseEntity.ok().body(json);
        }
        catch(Exception e){
            json.setMessage(e.getMessage());
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }
    }

    @GetMapping("/api/teaching/getStudentList")
    public ResponseEntity<?> getStudentList(@RequestHeader Map<String, String> header,
                                            @RequestParam("cid") int cid){
        MyJson json = new MyJson();
        String token = header.get("token");
        DecodedJWT jwt;
        boolean test = token == null;
        String username;
        try{
            jwt = JWTUtil.verifyToken(token);
            int userType = jwt.getClaim("usertype").asInt();
            username = jwt.getClaim("username").asString();
            if(userType != UserType.TEACHER){
                json.setMessage("Insufficient permission");
                json.setStatus(400);
                json.addData("status", 400);
                return ResponseEntity.ok().body(json);
            }
        }
        catch(TokenExpiredException e){
            json.setMessage("This token is expired");
            json.setStatus(400);
            json.addData("status", 400);
            return ResponseEntity.ok().body(json);
        }
        catch(Exception e){
            json.setMessage(e.getMessage());
            json.setStatus(400);
            json.addData("status", 0);
            return ResponseEntity.ok().body(json);
        }

        List<Teaching> list = teacherService.getTeachingList(username);
        boolean flag = false;
        for(Teaching teaching : list){
            if(teaching.getCid() == cid){
                flag = true;
                break;
            }
        }

        if(!flag){
            json.setMessage("Insufficient permission");
            json.setStatus(400);
            json.addData("status", 400);
            return ResponseEntity.ok().body(json);
        }

        Teaching t = teachingService.searchTeaching(cid);
        if(t == null){
            json.setMessage("WRONG cid");
            json.setStatus(400);
            json.addData("status", 400);
            return ResponseEntity.ok().body(json);
        }
        else{
            json.setMessage("Success");
            json.setStatus(200);
            json.addData("status", 0);
            System.out.println(t.getStudentList());
            List<StudentItem> studentItems = new ArrayList<>();
            for(Student s : t.getStudentList()){
                StudentItem item = new StudentItem(s.getSno(), s.getSname());
                studentItems.add(item);
            }
            json.addData("StudentList", studentItems);
            return ResponseEntity.ok().body(json);
        }
    }

    private static class CoursewareItem{

        public int coursewareid;
        public String name;
        public CoursewareItem(int coursewareid, String name) {
            this.coursewareid = coursewareid;
            this.name = name;
        }
    }
    private static class StudentItem{
        public String sno;
        public String name;

        public StudentItem(String sno, String name) {
            this.sno = sno;
            this.name = name;
        }
    }
}
